package com.cq.hd.common.handle;

import com.cq.hd.common.exception.BusinessException;
import com.cq.hd.common.exception.HttpExecuteException;
import com.cq.hd.common.exception.RpcCallException;
import com.cq.hd.common.response.Result;
import com.cq.hd.common.response.ResultGenerator;
import com.cq.hd.common.enums.ResponseEnums;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.Objects;

/**
 * @description: 全局异常处理
 * @author: mYunYu
 * @date: 2021/7/7 15:46
 * @version: v1.0
 */
@Slf4j
@ControllerAdvice
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class ExceptionHandle {

    /**
     * @description: 全局异常
     * @author: mYunYu
     * @date: 2020/6/10 17:37
     */
    @ResponseBody
    @ExceptionHandler(value = Exception.class)
    public Result<Object> handler(Exception ex) {
        log.error("ExceptionHandle捕获到Exception：{}, 堆栈信息：{}", ex.getMessage(), ex);
        if (ex.getMessage() != null && ex.getMessage().contains("com.netflix.client.ClientException")) {
            // feign的异常message放到data会导致上游服务继续进入异常，这里把data置空
            return ResultGenerator.error(ResponseEnums.ERROR.getCode(), ResponseEnums.ERROR.getMessage(), null);
        }
        return ResultGenerator.error(ResponseEnums.ERROR.getCode(), ResponseEnums.ERROR.getMessage(), ex.getMessage());
    }

    /**
     * @description: RPC 调用异常
     * @author: mYunYu
     * @date: 2020/6/10 17:49
     */
    @ResponseBody
    @ExceptionHandler(value = RpcCallException.class)
    public Result<Object> handler(RpcCallException ex) {
        log.error("ExceptionHandle捕获到RpcCallException：{}, 堆栈信息：{}", ex.getMessage(), ex.getStackTrace());
        return ResultGenerator.error(ex.getCode(), ex.getMessage());
    }

    /**
     * @description: RPC 调用异常
     * @author: mYunYu
     * @date: 2020/6/10 17:49
     */
    @ResponseBody
    @ExceptionHandler(value = HttpExecuteException.class)
    public Result<Object> handler(HttpExecuteException ex) {
        log.error("ExceptionHandle捕获到RpcCallException：{}, 堆栈信息：{}", ex.getMessage(), ex.getStackTrace());
        return ResultGenerator.error(ex.getCode(), ex.getMessage());
    }

    /**
     * @description: 业务异常
     * @author: mYunYu
     * @date: 2020/6/11 17:55
     */
    @ResponseBody
    @ExceptionHandler(value = BusinessException.class)
    public Result<Object> handler(BusinessException ex) {
        log.error("ExceptionHandle捕获到BusinessException：{}, 堆栈信息：{}", ex.getMessage(), ex.getStackTrace());
        return ResultGenerator.error(ex.getCode(), ex.getMessage());
    }

    /**
     * @description: 方法参数校验异常
     * @author: mYunYu
     * @date: 2020/9/28 09:55
     */
    @ResponseBody
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result<Object> handleMethodArgumentNotValidException(MethodArgumentNotValidException ex) {
        log.error("ExceptionHandle捕获到MethodArgumentNotValidException:{}, 堆栈信息：{}", ex.getMessage(), ex.getStackTrace());
        return ResultGenerator.error(Objects.requireNonNull(ex.getBindingResult().getFieldError()).getDefaultMessage());
    }

}
